/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.qsdm.es.dao;

import com.qsdm.es.dao.exceptions.IllegalOrphanException;
import com.qsdm.es.dao.exceptions.NonexistentEntityException;
import com.qsdm.es.dao.exceptions.PreexistingEntityException;
import com.qsdm.es.persistence.*;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author alberto
 */
public class UsuarioJpaController extends BasicJpaController {

    public void create(Usuario usuario) throws PreexistingEntityException, Exception {
        if (usuario.getUsuarioidiomaList() == null) {
            usuario.setUsuarioidiomaList(new ArrayList<Usuarioidioma>());
        }
        if (usuario.getUsuariocompetenciaList() == null) {
            usuario.setUsuariocompetenciaList(new ArrayList<Usuariocompetencia>());
        }
        if (usuario.getExperiencialaboralList() == null) {
            usuario.setExperiencialaboralList(new ArrayList<Experiencialaboral>());
        }
        if (usuario.getUsuarioformacionList() == null) {
            usuario.setUsuarioformacionList(new ArrayList<Usuarioformacion>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Municipio municipio = usuario.getMunicipio();
            if (municipio != null) {
                municipio = em.getReference(municipio.getClass(), municipio.getId());
                usuario.setMunicipio(municipio);
            }
            List<Usuarioidioma> attachedUsuarioidiomaList = new ArrayList<Usuarioidioma>();
            for (Usuarioidioma usuarioidiomaListUsuarioidiomaToAttach : usuario.getUsuarioidiomaList()) {
                usuarioidiomaListUsuarioidiomaToAttach = em.getReference(usuarioidiomaListUsuarioidiomaToAttach.getClass(), usuarioidiomaListUsuarioidiomaToAttach.getUsuarioidiomaPK());
                attachedUsuarioidiomaList.add(usuarioidiomaListUsuarioidiomaToAttach);
            }
            usuario.setUsuarioidiomaList(attachedUsuarioidiomaList);
            List<Usuariocompetencia> attachedUsuariocompetenciaList = new ArrayList<Usuariocompetencia>();
            for (Usuariocompetencia usuariocompetenciaListUsuariocompetenciaToAttach : usuario.getUsuariocompetenciaList()) {
                usuariocompetenciaListUsuariocompetenciaToAttach = em.getReference(usuariocompetenciaListUsuariocompetenciaToAttach.getClass(), usuariocompetenciaListUsuariocompetenciaToAttach.getUsuariocompetenciaPK());
                attachedUsuariocompetenciaList.add(usuariocompetenciaListUsuariocompetenciaToAttach);
            }
            usuario.setUsuariocompetenciaList(attachedUsuariocompetenciaList);
            List<Experiencialaboral> attachedExperiencialaboralList = new ArrayList<Experiencialaboral>();
            for (Experiencialaboral experiencialaboralListExperiencialaboralToAttach : usuario.getExperiencialaboralList()) {
                experiencialaboralListExperiencialaboralToAttach = em.getReference(experiencialaboralListExperiencialaboralToAttach.getClass(), experiencialaboralListExperiencialaboralToAttach.getId());
                attachedExperiencialaboralList.add(experiencialaboralListExperiencialaboralToAttach);
            }
            usuario.setExperiencialaboralList(attachedExperiencialaboralList);
            List<Usuarioformacion> attachedUsuarioformacionList = new ArrayList<Usuarioformacion>();
            for (Usuarioformacion usuarioformacionListUsuarioformacionToAttach : usuario.getUsuarioformacionList()) {
                usuarioformacionListUsuarioformacionToAttach = em.getReference(usuarioformacionListUsuarioformacionToAttach.getClass(), usuarioformacionListUsuarioformacionToAttach.getUsuarioformacionPK());
                attachedUsuarioformacionList.add(usuarioformacionListUsuarioformacionToAttach);
            }
            usuario.setUsuarioformacionList(attachedUsuarioformacionList);
            em.persist(usuario);
            if (municipio != null) {
                municipio.getUsuarioList().add(usuario);
                municipio = em.merge(municipio);
            }
            for (Usuarioidioma usuarioidiomaListUsuarioidioma : usuario.getUsuarioidiomaList()) {
                Usuario oldUsuario1OfUsuarioidiomaListUsuarioidioma = usuarioidiomaListUsuarioidioma.getUsuario1();
                usuarioidiomaListUsuarioidioma.setUsuario1(usuario);
                usuarioidiomaListUsuarioidioma = em.merge(usuarioidiomaListUsuarioidioma);
                if (oldUsuario1OfUsuarioidiomaListUsuarioidioma != null) {
                    oldUsuario1OfUsuarioidiomaListUsuarioidioma.getUsuarioidiomaList().remove(usuarioidiomaListUsuarioidioma);
                    oldUsuario1OfUsuarioidiomaListUsuarioidioma = em.merge(oldUsuario1OfUsuarioidiomaListUsuarioidioma);
                }
            }
            for (Usuariocompetencia usuariocompetenciaListUsuariocompetencia : usuario.getUsuariocompetenciaList()) {
                Usuario oldUsuario1OfUsuariocompetenciaListUsuariocompetencia = usuariocompetenciaListUsuariocompetencia.getUsuario1();
                usuariocompetenciaListUsuariocompetencia.setUsuario1(usuario);
                usuariocompetenciaListUsuariocompetencia = em.merge(usuariocompetenciaListUsuariocompetencia);
                if (oldUsuario1OfUsuariocompetenciaListUsuariocompetencia != null) {
                    oldUsuario1OfUsuariocompetenciaListUsuariocompetencia.getUsuariocompetenciaList().remove(usuariocompetenciaListUsuariocompetencia);
                    oldUsuario1OfUsuariocompetenciaListUsuariocompetencia = em.merge(oldUsuario1OfUsuariocompetenciaListUsuariocompetencia);
                }
            }
            for (Experiencialaboral experiencialaboralListExperiencialaboral : usuario.getExperiencialaboralList()) {
                Usuario oldUsuarioOfExperiencialaboralListExperiencialaboral = experiencialaboralListExperiencialaboral.getUsuario();
                experiencialaboralListExperiencialaboral.setUsuario(usuario);
                experiencialaboralListExperiencialaboral = em.merge(experiencialaboralListExperiencialaboral);
                if (oldUsuarioOfExperiencialaboralListExperiencialaboral != null) {
                    oldUsuarioOfExperiencialaboralListExperiencialaboral.getExperiencialaboralList().remove(experiencialaboralListExperiencialaboral);
                    oldUsuarioOfExperiencialaboralListExperiencialaboral = em.merge(oldUsuarioOfExperiencialaboralListExperiencialaboral);
                }
            }
            for (Usuarioformacion usuarioformacionListUsuarioformacion : usuario.getUsuarioformacionList()) {
                Usuario oldUsuarioOfUsuarioformacionListUsuarioformacion = usuarioformacionListUsuarioformacion.getUsuario();
                usuarioformacionListUsuarioformacion.setUsuario(usuario);
                usuarioformacionListUsuarioformacion = em.merge(usuarioformacionListUsuarioformacion);
                if (oldUsuarioOfUsuarioformacionListUsuarioformacion != null) {
                    oldUsuarioOfUsuarioformacionListUsuarioformacion.getUsuarioformacionList().remove(usuarioformacionListUsuarioformacion);
                    oldUsuarioOfUsuarioformacionListUsuarioformacion = em.merge(oldUsuarioOfUsuarioformacionListUsuarioformacion);
                }
            }
            
        } catch (Exception ex) {
            if (findUsuario(usuario.getId()) != null) {
                throw new PreexistingEntityException("Usuario " + usuario + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getId());
            Municipio municipioOld = persistentUsuario.getMunicipio();
            Municipio municipioNew = usuario.getMunicipio();
            List<Usuarioidioma> usuarioidiomaListOld = persistentUsuario.getUsuarioidiomaList();
            List<Usuarioidioma> usuarioidiomaListNew = usuario.getUsuarioidiomaList();
            List<Usuariocompetencia> usuariocompetenciaListOld = persistentUsuario.getUsuariocompetenciaList();
            List<Usuariocompetencia> usuariocompetenciaListNew = usuario.getUsuariocompetenciaList();
            List<Experiencialaboral> experiencialaboralListOld = persistentUsuario.getExperiencialaboralList();
            List<Experiencialaboral> experiencialaboralListNew = usuario.getExperiencialaboralList();
            List<Usuarioformacion> usuarioformacionListOld = persistentUsuario.getUsuarioformacionList();
            List<Usuarioformacion> usuarioformacionListNew = usuario.getUsuarioformacionList();
            List<String> illegalOrphanMessages = null;
            for (Usuarioidioma usuarioidiomaListOldUsuarioidioma : usuarioidiomaListOld) {
                if (!usuarioidiomaListNew.contains(usuarioidiomaListOldUsuarioidioma)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Usuarioidioma " + usuarioidiomaListOldUsuarioidioma + " since its usuario1 field is not nullable.");
                }
            }
            for (Usuariocompetencia usuariocompetenciaListOldUsuariocompetencia : usuariocompetenciaListOld) {
                if (!usuariocompetenciaListNew.contains(usuariocompetenciaListOldUsuariocompetencia)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Usuariocompetencia " + usuariocompetenciaListOldUsuariocompetencia + " since its usuario1 field is not nullable.");
                }
            }
            for (Usuarioformacion usuarioformacionListOldUsuarioformacion : usuarioformacionListOld) {
                if (!usuarioformacionListNew.contains(usuarioformacionListOldUsuarioformacion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Usuarioformacion " + usuarioformacionListOldUsuarioformacion + " since its usuario field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (municipioNew != null) {
                municipioNew = em.getReference(municipioNew.getClass(), municipioNew.getId());
                usuario.setMunicipio(municipioNew);
            }
            List<Usuarioidioma> attachedUsuarioidiomaListNew = new ArrayList<Usuarioidioma>();
            for (Usuarioidioma usuarioidiomaListNewUsuarioidiomaToAttach : usuarioidiomaListNew) {
                usuarioidiomaListNewUsuarioidiomaToAttach = em.getReference(usuarioidiomaListNewUsuarioidiomaToAttach.getClass(), usuarioidiomaListNewUsuarioidiomaToAttach.getUsuarioidiomaPK());
                attachedUsuarioidiomaListNew.add(usuarioidiomaListNewUsuarioidiomaToAttach);
            }
            usuarioidiomaListNew = attachedUsuarioidiomaListNew;
            usuario.setUsuarioidiomaList(usuarioidiomaListNew);
            List<Usuariocompetencia> attachedUsuariocompetenciaListNew = new ArrayList<Usuariocompetencia>();
            for (Usuariocompetencia usuariocompetenciaListNewUsuariocompetenciaToAttach : usuariocompetenciaListNew) {
                usuariocompetenciaListNewUsuariocompetenciaToAttach = em.getReference(usuariocompetenciaListNewUsuariocompetenciaToAttach.getClass(), usuariocompetenciaListNewUsuariocompetenciaToAttach.getUsuariocompetenciaPK());
                attachedUsuariocompetenciaListNew.add(usuariocompetenciaListNewUsuariocompetenciaToAttach);
            }
            usuariocompetenciaListNew = attachedUsuariocompetenciaListNew;
            usuario.setUsuariocompetenciaList(usuariocompetenciaListNew);
            List<Experiencialaboral> attachedExperiencialaboralListNew = new ArrayList<Experiencialaboral>();
            for (Experiencialaboral experiencialaboralListNewExperiencialaboralToAttach : experiencialaboralListNew) {
                experiencialaboralListNewExperiencialaboralToAttach = em.getReference(experiencialaboralListNewExperiencialaboralToAttach.getClass(), experiencialaboralListNewExperiencialaboralToAttach.getId());
                attachedExperiencialaboralListNew.add(experiencialaboralListNewExperiencialaboralToAttach);
            }
            experiencialaboralListNew = attachedExperiencialaboralListNew;
            usuario.setExperiencialaboralList(experiencialaboralListNew);
            List<Usuarioformacion> attachedUsuarioformacionListNew = new ArrayList<Usuarioformacion>();
            for (Usuarioformacion usuarioformacionListNewUsuarioformacionToAttach : usuarioformacionListNew) {
                usuarioformacionListNewUsuarioformacionToAttach = em.getReference(usuarioformacionListNewUsuarioformacionToAttach.getClass(), usuarioformacionListNewUsuarioformacionToAttach.getUsuarioformacionPK());
                attachedUsuarioformacionListNew.add(usuarioformacionListNewUsuarioformacionToAttach);
            }
            usuarioformacionListNew = attachedUsuarioformacionListNew;
            usuario.setUsuarioformacionList(usuarioformacionListNew);
            usuario = em.merge(usuario);
            if (municipioOld != null && !municipioOld.equals(municipioNew)) {
                municipioOld.getUsuarioList().remove(usuario);
                municipioOld = em.merge(municipioOld);
            }
            if (municipioNew != null && !municipioNew.equals(municipioOld)) {
                municipioNew.getUsuarioList().add(usuario);
                municipioNew = em.merge(municipioNew);
            }
            for (Usuarioidioma usuarioidiomaListNewUsuarioidioma : usuarioidiomaListNew) {
                if (!usuarioidiomaListOld.contains(usuarioidiomaListNewUsuarioidioma)) {
                    Usuario oldUsuario1OfUsuarioidiomaListNewUsuarioidioma = usuarioidiomaListNewUsuarioidioma.getUsuario1();
                    usuarioidiomaListNewUsuarioidioma.setUsuario1(usuario);
                    usuarioidiomaListNewUsuarioidioma = em.merge(usuarioidiomaListNewUsuarioidioma);
                    if (oldUsuario1OfUsuarioidiomaListNewUsuarioidioma != null && !oldUsuario1OfUsuarioidiomaListNewUsuarioidioma.equals(usuario)) {
                        oldUsuario1OfUsuarioidiomaListNewUsuarioidioma.getUsuarioidiomaList().remove(usuarioidiomaListNewUsuarioidioma);
                        oldUsuario1OfUsuarioidiomaListNewUsuarioidioma = em.merge(oldUsuario1OfUsuarioidiomaListNewUsuarioidioma);
                    }
                }
            }
            for (Usuariocompetencia usuariocompetenciaListNewUsuariocompetencia : usuariocompetenciaListNew) {
                if (!usuariocompetenciaListOld.contains(usuariocompetenciaListNewUsuariocompetencia)) {
                    Usuario oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia = usuariocompetenciaListNewUsuariocompetencia.getUsuario1();
                    usuariocompetenciaListNewUsuariocompetencia.setUsuario1(usuario);
                    usuariocompetenciaListNewUsuariocompetencia = em.merge(usuariocompetenciaListNewUsuariocompetencia);
                    if (oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia != null && !oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia.equals(usuario)) {
                        oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia.getUsuariocompetenciaList().remove(usuariocompetenciaListNewUsuariocompetencia);
                        oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia = em.merge(oldUsuario1OfUsuariocompetenciaListNewUsuariocompetencia);
                    }
                }
            }
            for (Experiencialaboral experiencialaboralListOldExperiencialaboral : experiencialaboralListOld) {
                if (!experiencialaboralListNew.contains(experiencialaboralListOldExperiencialaboral)) {
                    experiencialaboralListOldExperiencialaboral.setUsuario(null);
                    experiencialaboralListOldExperiencialaboral = em.merge(experiencialaboralListOldExperiencialaboral);
                }
            }
            for (Experiencialaboral experiencialaboralListNewExperiencialaboral : experiencialaboralListNew) {
                if (!experiencialaboralListOld.contains(experiencialaboralListNewExperiencialaboral)) {
                    Usuario oldUsuarioOfExperiencialaboralListNewExperiencialaboral = experiencialaboralListNewExperiencialaboral.getUsuario();
                    experiencialaboralListNewExperiencialaboral.setUsuario(usuario);
                    experiencialaboralListNewExperiencialaboral = em.merge(experiencialaboralListNewExperiencialaboral);
                    if (oldUsuarioOfExperiencialaboralListNewExperiencialaboral != null && !oldUsuarioOfExperiencialaboralListNewExperiencialaboral.equals(usuario)) {
                        oldUsuarioOfExperiencialaboralListNewExperiencialaboral.getExperiencialaboralList().remove(experiencialaboralListNewExperiencialaboral);
                        oldUsuarioOfExperiencialaboralListNewExperiencialaboral = em.merge(oldUsuarioOfExperiencialaboralListNewExperiencialaboral);
                    }
                }
            }
            for (Usuarioformacion usuarioformacionListNewUsuarioformacion : usuarioformacionListNew) {
                if (!usuarioformacionListOld.contains(usuarioformacionListNewUsuarioformacion)) {
                    Usuario oldUsuarioOfUsuarioformacionListNewUsuarioformacion = usuarioformacionListNewUsuarioformacion.getUsuario();
                    usuarioformacionListNewUsuarioformacion.setUsuario(usuario);
                    usuarioformacionListNewUsuarioformacion = em.merge(usuarioformacionListNewUsuarioformacion);
                    if (oldUsuarioOfUsuarioformacionListNewUsuarioformacion != null && !oldUsuarioOfUsuarioformacionListNewUsuarioformacion.equals(usuario)) {
                        oldUsuarioOfUsuarioformacionListNewUsuarioformacion.getUsuarioformacionList().remove(usuarioformacionListNewUsuarioformacion);
                        oldUsuarioOfUsuarioformacionListNewUsuarioformacion = em.merge(oldUsuarioOfUsuarioformacionListNewUsuarioformacion);
                    }
                }
            }
            
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = usuario.getId();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Usuarioidioma> usuarioidiomaListOrphanCheck = usuario.getUsuarioidiomaList();
            for (Usuarioidioma usuarioidiomaListOrphanCheckUsuarioidioma : usuarioidiomaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Usuarioidioma " + usuarioidiomaListOrphanCheckUsuarioidioma + " in its usuarioidiomaList field has a non-nullable usuario1 field.");
            }
            List<Usuariocompetencia> usuariocompetenciaListOrphanCheck = usuario.getUsuariocompetenciaList();
            for (Usuariocompetencia usuariocompetenciaListOrphanCheckUsuariocompetencia : usuariocompetenciaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Usuariocompetencia " + usuariocompetenciaListOrphanCheckUsuariocompetencia + " in its usuariocompetenciaList field has a non-nullable usuario1 field.");
            }
            List<Usuarioformacion> usuarioformacionListOrphanCheck = usuario.getUsuarioformacionList();
            for (Usuarioformacion usuarioformacionListOrphanCheckUsuarioformacion : usuarioformacionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Usuarioformacion " + usuarioformacionListOrphanCheckUsuarioformacion + " in its usuarioformacionList field has a non-nullable usuario field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Municipio municipio = usuario.getMunicipio();
            if (municipio != null) {
                municipio.getUsuarioList().remove(usuario);
                municipio = em.merge(municipio);
            }
            List<Experiencialaboral> experiencialaboralList = usuario.getExperiencialaboralList();
            for (Experiencialaboral experiencialaboralListExperiencialaboral : experiencialaboralList) {
                experiencialaboralListExperiencialaboral.setUsuario(null);
                experiencialaboralListExperiencialaboral = em.merge(experiencialaboralListExperiencialaboral);
            }
            em.remove(usuario);
            
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
